package com.ruoyi.business.service.impl;

import com.ruoyi.business.service.IProcessService;
import com.ruoyi.common.utils.ShiroUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

@Service
@Transactional
public class ProcessServiceImpl implements IProcessService {

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;


    @Override
    public Deployment deploy(String filePath) throws IOException {

        Deployment deployment = null;
        if(filePath.endsWith("zip")){
            //zip
            deployment = repositoryService.createDeployment()
                    .addZipInputStream(new ZipInputStream(new FileInputStream(filePath)))
                    .deploy();
        }else if (filePath.endsWith("bpmn")){
            //bpmn
            deployment = repositoryService.createDeployment()
                    .addInputStream(filePath, new FileInputStream(filePath) )
                    .deploy();
        }
        return deployment;
    }

    @Override
    public ProcessDefinition selectProcessDefinitionByDeploymentId(String deploymentId) {
        return repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId)
                .singleResult();
    }

    @Override
    public InputStream getResourceAsStream(String deploymentId, String resourceName) {

        return repositoryService.getResourceAsStream(deploymentId, resourceName);
    }

    @Override
    public InputStream getProcessImage(String processDefinitionId,
                                       List<String> highLightedActivities,
                                       List<String> highLightedFlows) {


        BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        //generateDiagram(流程模型,需要高亮的节点,需要高亮的线条,后面三个参数都表示是字体)
        InputStream inputStream =
                generator.generateDiagram(model, highLightedActivities, highLightedFlows,"宋体","宋体","宋体");
        return inputStream;
    }

    @Override
    public ProcessInstance startProcessInstanceByKey
            (String definitionKey, String businessKey, Map<String, Object> map) {

        return runtimeService.startProcessInstanceByKey(definitionKey,businessKey,map);
    }

    @Override
    public Task getTaskByInstanceId(String instanceId) {


        return taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
    }

    @Override
    public void addCandidateUser(String taskId, String userId) {
        taskService.addCandidateUser(taskId, userId);
    }

    @Override
    public List<String> getActiveActivityIds(String instanceId) {
        //方法中使用参数名称写是excutionid 如果使用instanceId也可以达到相同效果
        Task task = this.getTaskByInstanceId(instanceId);
        System.out.println(task.getExecutionId() + "---------------------" + instanceId);
        return runtimeService.getActiveActivityIds(task.getExecutionId());
        //return runtimeService.getActiveActivityIds(instanceId);
    }

    @Override
    public void deleteProcessInstance(String instanceId, String msg) {
        runtimeService.deleteProcessInstance(instanceId, msg);
    }

    @Override
    public List<Task> selectTodoTaskList(String processDefinitionKey, String userId,
                                         Integer startNum, Integer pageSize) {
        return  taskService.createTaskQuery()
                .taskCandidateUser(userId)
                .processDefinitionKey(processDefinitionKey)
                //.list();
                .listPage(startNum,pageSize);
    }

    @Override
    public ProcessInstance getProcessInstanceById(String processInstanceId) {
        return runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
    }

    @Override
    public Long selectTodoTaskCount(String definitionKey, String userId) {
        return taskService.createTaskQuery()
                .taskCandidateUser(userId)
                .processDefinitionKey(definitionKey)
                .count();
    }

    @Override
    public Task getTaskById(String taskId) {
        return taskService.createTaskQuery().taskId(taskId).singleResult();
    }

    @Override
    public void claimAndComplete(Task task, String userId,  Boolean auditStatus, String comment) {
        //领取任务
        taskService.claim(task.getId(), userId);
        //设置参数
        //task.getTaskDefinitionKey() 在流程节点定义时就指定：shopOwnerAudit  presidentAudit  financialAudit
        taskService.setVariable(task.getId(),task.getTaskDefinitionKey(), auditStatus);
        //设置备注
        taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
        //执行
        taskService.complete(task.getId());

    }

    @Override
    public void setVariable(Task task, String name, Object value) {
        taskService.setVariable(task.getId(),name, value);
    }

    @Override
    public List<HistoricTaskInstance> selectDoneTaskList(String definitionKey, String userId, Integer startNum, Integer pageSize) {

        return historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(definitionKey)
                .taskAssignee(userId)
                .finished()  //已经完成记录
                .orderByHistoricTaskInstanceEndTime()  //结束时间排序
                .desc()
                .listPage(startNum,pageSize);
    }

    @Override
    public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
        return historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
    }

    @Override
    public Long selectDoneTaskCount(String definitionKey, String userId) {
        return historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(definitionKey)
                .taskAssignee(userId)
                .finished()  //已经完成记录
                .count();
    }

    @Override
    public List<HistoricActivityInstance> selectHistoryList(String instanceId) {
        return historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .activityType("userTask")
                .finished()
                .orderByHistoricActivityInstanceStartTime()
                .desc()
                .list();
    }

    @Override
    public String getTaskComment(String taskId) {

        List<Comment> taskComments = taskService.getTaskComments(taskId, "comment");
        if(taskComments!=null && taskComments.size()>0){
            return taskComments.get(0).getFullMessage();
        }else{
            return "";
        }
    }
}
